<template>
  <!-- 弹框 -->
  <!--
      当点击叉号的时候并没有修改父组件中的dialogVisible
      在组件内部触发了一个自定义事件 close

      .sync
      表现: 加上这个修饰符之后 我们不再需要手动绑定一个close自定义事件点击叉号同样可以关闭弹框
      内部实现: 加上.sync修饰符之后形成了一个叫做`基于props的双向绑定` 其实就是在内部自动绑定了一个函数
      在函数体里帮助我们完成了对于dialogVisible属性的自动赋值

      不推荐使用
     -->
  <el-dialog
    title="提示"
    :visible="showDialog"
    width="30%"
    @close="closeDialog"
    @open="openDialog"
  >
    <!-- 表单 -->
    <el-form ref="addForm" label-width="120px" :model="form" :rules="rules">
      <el-form-item label="部门名称" prop="name">
        <el-input v-model="form.name" style="width:80%" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门编码" prop="code">
        <el-input v-model="form.code" style="width:80%" placeholder="1-50个字符" />
      </el-form-item>
      <el-form-item label="部门负责人" prop="manager">
        <el-select v-model="form.manager" placeholder="请选择">
          <!-- label就是中文文案 value就是选中的值将来会自动放到form.manager上 -->
          <el-option
            v-for="item in employeeList"
            :key="item.id"
            :label="item.username"
            :value="item.username"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="部门介绍" prop="introduce">
        <el-input v-model="form.introduce" style="width:80%" placeholder="1-300个字符" type="textarea" />
      </el-form-item>
    </el-form>
    <!-- 具名插槽 -->
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="showDialog = false">取 消</el-button>
        <el-button type="primary" @click="confirm">确 定</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script>
import { getEmployeeSimple } from '@/api/employee'
import { addDepartments, getDepartDetail, updateDepartments } from '@/api/department'
export default {
  props: {
    showDialog: {
      type: Boolean
    },
    curId: {
      type: String,
      default: ''
    },
    codeList: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data() {
    // 定义一个针对于code不能重复的校验函数
    const validateCode = (rule, value, callback) => {
      // 添加code非重逻辑
      // 思路：使用value去已经存在的列表中去找 如果找得到就重复了 校验不过 如果找不到 不重复 校验通过
      // 1. 通过父传子把数据传过来
      // 2. 去数组中去找 includes
      // 3. 在拿到原数组之后有一步树形结构处理的,不方便做数组查找 传下来的应该是一个未经过处理的原数组

      // 产生问题的原因: 当前输入code回填的数据 能在codeList中找到
      // 解决问题的思路: 在编辑的情况下 用作判断的codeList中应该先过滤掉当前回显时的数据code
      // 具体的核心点：
      //  1. 数组过滤 filter
      //  2. 拿到当前输入框中code 现在的数据(由于form中的code和表单元素有双向绑定的关系 只有有输入修改就会被同步改掉，本来用作判断条件的初始code丢失)
      //     另起一个单独的专门用来存放初始code的属性
      let _codeList = [] // 叫来作为判断条件的codeList
      if (this.form.id) {
        // 编辑
        _codeList = this.codeList.filter(item => item !== this.cacheCode)
      } else {
        _codeList = this.codeList
      }
      if (_codeList.includes(value)) {
        // 找到了
        callback(new Error('code码不能出现重复'))
      } else {
        callback()
      }
    }
    return {
      form: {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '' // 部门介绍
      },
      cacheCode: '', // 存放初始code
      rules: {
        name: [
          { required: true, message: '部门名称不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门名称要求1-50个字符', trigger: ['blur', 'change'] }
        ],
        code: [
          { required: true, message: '部门编码不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 50, message: '部门编码要求1-50个字符', trigger: ['blur', 'change'] },
          { validator: validateCode, message: '部门编码不能出现重复', trigger: 'blur' }
        ],
        manager: [
          { required: true, message: '部门负责人不能为空', trigger: ['blur', 'change'] }
        ],
        introduce: [
          { required: true, message: '部门介绍不能为空', trigger: ['blur', 'change'] },
          { min: 1, max: 300, message: '部门介绍要求1-300个字符', trigger: ['blur', 'change'] }
        ]
      },
      employeeList: [] // 下拉员工列表
    }
  },
  methods: {
    closeDialog() {
      this.$emit('close-dialog')
      // 初始化数据 清除校验结果
      this.form = {
        name: '', // 部门名称
        code: '', // 部门编码
        manager: '', // 部门管理者
        introduce: '' // 部门介绍
      }
      // bug：resetFields方法只能初始化 默认绑定的字段 新增的字段无法处理
      this.$refs.addForm.resetFields()
    },
    // 获取员工列表
    async hGetEmployeeList() {
      const res = await getEmployeeSimple()
      this.employeeList = res.data
    },
    openDialog() {
      this.hGetEmployeeList()
      // 获取详情的接口发起
      // 新增业务同样可以调起来这个方法 但是新增是不需要回显
      // this.getDetail()
    },
    // 提交表单接口调用
    confirm() {
      // 新增和编辑都是通过确定按钮 走confirm方法
      // 所以我们需要做当前是新增还是编辑逻辑判断 如果是新增就调用新增接口 如果是编辑就走更新接口
      // 1. 兜底校验
      this.$refs.addForm.validate(async(valid) => {
        if (valid) {
          // 做新增还是编辑的判断 -> form中是否有id 如果有就是编辑  没有就是新增
          if (this.form.id) {
            // todo edit
            await updateDepartments(this.form)
          } else {
            // 2. 调用新增接口
            await addDepartments({ ...this.form, pid: this.curId })
          }
          // 3. 通知父组件更新列表
          this.$emit('update-list')
          // 4. 关闭弹框
          this.closeDialog()
        }
      })
    },
    // 详情数据拉取 搞定id 方法调用(点击编辑按钮之后 id传过去之后)
    //
    async getDetail(id) {
      // 调用接口 回填数据
      const res = await getDepartDetail(id)
      this.form = res.data
      // 把一开始的code 交给cacheCode暂存起来
      this.cacheCode = res.data.code
    }
  }
}
</script>

